import os
import time
from io import StringIO

import requests

from conf import Config as myconf

from loguru import logger

from dl.download_ref_pdf import DRPdf
from models.table_defs import PaperReference

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

def getIeeeJournalFormat(bibInfo):
  """
  生成期刊文献的IEEE引用格式：{作者}, "{文章标题}," {期刊名称}, vol. {卷数}, no. {编号}, pp. {页码}, {年份}.
  :return: {author}, "{title}," {journal}, vol. {volume}, no. {number}, pp. {pages}, {year}.
  """
  # 避免字典出现null值
  if "volume" not in bibInfo:
    bibInfo["volume"] = "null"
  if "number" not in bibInfo:
    bibInfo["number"] = "null"
  if "pages" not in bibInfo:
    bibInfo["pages"] = "null"

  authors = ", ".join(bibInfo["author"])  if isinstance(bibInfo["author"], list) else bibInfo["author"]
  journalFormat = authors + \
                  ", \"" + bibInfo["title"] + \
                  ",\" " + bibInfo["journal"] + \
                  ", vol. " + bibInfo["volume"] + \
                  ", no. " + bibInfo["number"] + \
                  ", pp. " + bibInfo["pages"] + \
                  ", " + bibInfo["year"] + "."

  # 对格式进行调整，去掉没有的信息，调整页码格式
  journalFormatNormal = journalFormat.replace(", vol. null", "")
  journalFormatNormal = journalFormatNormal.replace(", no. null", "")
  journalFormatNormal = journalFormatNormal.replace(", pp. null", "")
  journalFormatNormal = journalFormatNormal.replace("--", "-")
  return journalFormatNormal

def get_reference_from_pdf(pdf_file):
  """
  从pdf文件中提取引用文献信息 原文
  :param pdf_file:
  :return: 引用文献信息 原文
  """

  # 调用第三方库pdfminer.six提取pdf文件中的引用文献信息 --> 暂未试
  page_number = -1
  last_page_text = DRPdf.pdf_to_txt(pdf_file, page_number)


  return last_page_text

getYMDHmsRand = lambda  : int(round(time.time() * 1000))

class QryByUnstructCitation:
  @classmethod
  def str_to_one_line(cls, s):
    # 将多行字符串转为一行
    return ''.join(s.split('\n'))

  @classmethod
  def build_qdata_xml_str(cls, unstructured_citations):
    from lxml import etree
    doi_batch_id = getYMDHmsRand()
    query_batch_xml_str = """<query_batch xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xmlns="http://www.crossref.org/qschema/2.0" xsi:schemaLocation="http://www.crossref.org/qschema/2.0 http://www.crossref.org/qschema/crossref_query_input2.0.xsd" > """
    xml_data = f'''<?xml version="1.0" ?>
    <query_batch><head><email_address>934096384@qq.com</email_address><doi_batch_id>{doi_batch_id}</doi_batch_id></head><body/></query_batch>
    '''
    f = StringIO(xml_data) # 如果把 query_batch_xml_str 的内容放到 xml_data 里，会导致后续 的 xpath 失灵
    tree = etree.parse(f)
    root = tree.getroot()
    bodyEl = root.xpath('//body')[0]
    for i, unstructured_citation in enumerate(unstructured_citations):
      queryEl = etree.SubElement(bodyEl, "query")
      queryEl.set("key", f"q{i + 1}")
      queryEl.set("enable-multiple-hits", "false")  # enable-multiple-hits="false"
      citation_el = etree.SubElement(queryEl, "unstructured_citation")
      citation_el.text = unstructured_citation

    xmlStr = etree.tostring(tree, encoding="utf-8", xml_declaration=True, pretty_print=False).decode("utf-8")
    xmlStr = xmlStr.replace('<query_batch>', query_batch_xml_str)
    return xmlStr

  @classmethod
  def query(cls, unstructured_citation):
    unstruct_citation = cls.str_to_one_line(unstructured_citation)
    params = {'usr': myconf.crossref_user, 'qdata': unstruct_citation, 'format': 'unixref'}
    response = requests.get(myconf.crossref_url0, params=params)
    if response.status_code == 200:
      return response.text

  @classmethod
  def xml_to_PaperReference(cls, elem):
    paper_ref = PaperReference()
    paper_ref.title = elem.findtext('.//journal_article//title')

    # 提取作者
    authors = []
    for author in elem.findall('.//journal_article//person_name'):
      given_name = author.findtext('given_name')
      surname = author.findtext('surname')
      authors.append(f"{given_name} {surname}")
    paper_ref.authors = ' , '.join(authors)

    # 提取期刊名称
    journal_title = elem.findtext('.//full_title')
    paper_ref.journal = journal_title

    # 提取出版日期
    year = elem.findtext('.//year')
    month = elem.findtext('.//month')
    day = elem.findtext('.//day')
    paper_ref.publication_date = f"{year}-{month}-{day}"
    paper_ref.year = f"{year}"

    # 提取页码
    first_page = elem.findtext('.//first_page')
    last_page = elem.findtext('.//last_page')
    paper_ref.pages = f"{first_page}-{last_page}"

    # 提取 DOI 和资源
    paper_ref.doi = elem.findtext('.//doi')
    paper_ref.resource = elem.findtext('.//resource')

    return paper_ref

  @classmethod
  def query_4_PaperReference(cls,unstructured_citation):
    from lxml import etree

    res_xml = cls.query(unstructured_citation)
    if res_xml:
      # 将字符串编码为字节类型
      res_xml_bytes = res_xml.encode('utf-8')
      root = etree.fromstring(res_xml_bytes)
      obj_list = []
      for doi_rec in root.xpath('doi_record'):
        journal_elem = doi_rec.xpath('crossref/journal')[0]
        if journal_elem is not None:
          paper_ref=cls.xml_to_PaperReference(journal_elem)
          obj_list.append(paper_ref)
      return obj_list
    else:
      return []

# test code

def test1():
  # 以上内容是 qwen2 输出的，prompt 如下： 任务：请从以上资料中提取并整理引用文献的信息（一般从 References之处开始），以标准的IEEE格式和json的格式返回
  bibInfo = {
    "author": [
      "National Diabetes Research Group"
    ],
    "title": "Diabetes mellitus survey of 300,000 in fourteen provinces and cities of China",
    "journal": "Chin MedJ",
    "volume": "20",
    "issue": "",
    "pages": "678-681",
    "year": "1981"
  }
  ieee_str = getIeeeJournalFormat(bibInfo)
  print(ieee_str)

def test_get_reference_from_pdf():
  pdf_file = r"E:\tmp\docu_dl_analyze\Haibo Wang NEJM-Trends+in+CKD+in+China.pdf"
  get_reference_from_pdf(pdf_file)
  pass

if __name__ == '__main__':
  # test1()
  test_get_reference_from_pdf()
